# -*- coding:utf-8 -*-

import os
import logging
import threading
from functools import wraps
from multiprocessing import Lock
from logging.handlers import TimedRotatingFileHandler

lock = Lock()


def locker(lk):
    def _locker(func):
        @wraps(func)
        def __locker(i, s):
            lk.acquire()
            func(i, s)
            lk.release()

        return __locker

    return _locker


class Log(object):
    _instance = None
    _instance_lock = threading.Lock()
    pro_log_file = os.path.join(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'logs'),
                                'DevOpsPlatform.log')

    def __new__(cls, *args, **kwargs):
        if not (hasattr(Log, '_instance')):
            with Log._instance_lock:
                if not hasattr(Log, '_instance'):
                    Log._instance = object.__new__(cls)
        return Log._instance

    def __init__(self, log_file=None, console=False):
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(level=logging.INFO)
        self.format = logging.Formatter(datefmt='%Z %z %A %Y-%m-%d %X',
                                        fmt='%(asctime)s | %(levelname)s | %(filename)s | %(funcName)s | %(message)s'
                                        )
        if not log_file:
            self.log_path = self.__make_dir(Log.pro_log_file)
            self.file_handler = Log.__file_handler(self.logger, Log.pro_log_file, self.format)

    @staticmethod
    def __make_dir(log_file):
        if '/' not in log_file:
            return

        log_path = log_file.rsplit('/', 1)[0]
        if not os.path.exists(log_path):
            os.makedirs(log_path)
        return 1

    @staticmethod
    def __file_handler(log_obj, log_file, for_mat):
        # TimedRotatingFileHandler 用于分割日志和日志数量控制
        handler = TimedRotatingFileHandler(filename=log_file, when='D', interval=1, backupCount=7)
        handler.setLevel(logging.INFO)
        handler.setFormatter(for_mat)
        log_obj.addHandler(handler)
        return 1

    @staticmethod
    def __stream_handler(log_obj, for_mat):
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        console.setFormatter(fmt=for_mat)
        log_obj.addHandler(console)

    def get_logger(self):
        return self.logger


if __name__ == '__main__':
    """
    测试使用
    """
    import multiprocessing

    logger = Log().get_logger()


    def func1():
        logger.info('This is function func1.')


    res = []
    for i in range(10):
        m = multiprocessing.Process(target=func1)
        res.append(m)

    for i in res:
        i.start()

    for i in res:
        i.join()
